package com.zenithmind.library.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.common.result.PageResult;
import com.zenithmind.common.result.Result;
import com.zenithmind.common.result.ResultCode;
import com.zenithmind.library.mapper.BookMapper;
import com.zenithmind.library.mapper.BookInventoryMapper;
import com.zenithmind.library.mapper.BookStatisticsMapper;
import com.zenithmind.library.pojo.domain.Book;
import com.zenithmind.library.pojo.domain.BookInventory;
import com.zenithmind.library.pojo.domain.BookStatistics;
import com.zenithmind.library.pojo.dto.BookCreateDTO;
import com.zenithmind.library.pojo.dto.BookUpdateDTO;
import com.zenithmind.library.pojo.query.BookQuery;
import com.zenithmind.library.pojo.vo.BookDetailVO;
import com.zenithmind.library.pojo.vo.BookVO;
import com.zenithmind.library.service.BookService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 图书服务实现类
 * 
 * @author ZenithMind
 * @since 2024-06-14
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements BookService {

    private final BookMapper bookMapper;
    private final BookInventoryMapper bookInventoryMapper;
    private final BookStatisticsMapper bookStatisticsMapper;

    @Override
    @Cacheable(value = "books", key = "'page:' + #query.hashCode()")
    public PageResult<BookVO> getBookPage(BookQuery query) {
        log.info("分页查询图书，查询条件：{}", query);

        Page<BookVO> page = query.toPage();
        IPage<BookVO> result = bookMapper.selectBookPage(page, query);

        return PageResult.of(result.getRecords(), result.getTotal(), result.getCurrent(), result.getSize());
    }

    @Override
    @Cacheable(value = "books", key = "'detail:' + #id")
    public BookDetailVO getBookDetail(String id) {
        log.info("查询图书详情，ID：{}", id);
        
        BookDetailVO bookDetail = bookMapper.selectBookDetailById(id);
        if (bookDetail == null) {
            throw new RuntimeException("图书不存在");
        }
        
        return bookDetail;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = "books", allEntries = true)
    public Result<BookVO> createBook(BookCreateDTO createDTO) {
        log.info("创建图书，数据：{}", createDTO);
        
        // 检查ISBN是否已存在
        if (checkIsbnExists(createDTO.getIsbn(), null)) {
            return Result.fail(ResultCode.CONFLICT.getCode(), "ISBN已存在", null);
        }
        
        // 转换为实体对象
        Book book = new Book();
        BeanUtils.copyProperties(createDTO, book);
        // 注意：库存和统计信息现在由单独的实体管理
        // 这里只设置图书基本信息，库存和统计信息将在后续步骤中创建
        book.setStatus(1); // 默认上架
        book.setCreateTime(LocalDateTime.now());
        book.setUpdateTime(LocalDateTime.now());
        
        // 保存图书
        boolean saved = save(book);
        if (!saved) {
            return Result.fail(ResultCode.FAIL.getCode(), "创建图书失败", null);
        }
        
        // 返回创建的图书信息
        BookVO bookVO = convertToVO(book);
        return Result.success(bookVO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = "books", allEntries = true)
    public Result<BookVO> updateBook(String id, BookUpdateDTO updateDTO) {
        log.info("更新图书，ID：{}，数据：{}", id, updateDTO);
        
        // 检查图书是否存在
        Book existingBook = getById(id);
        if (existingBook == null) {
            return Result.fail(ResultCode.NOT_FOUND.getCode(), "图书不存在", null);
        }
        
        // 检查ISBN是否已被其他图书使用
        if (StringUtils.hasText(updateDTO.getIsbn()) && 
            checkIsbnExists(updateDTO.getIsbn(), id)) {
            return Result.fail(ResultCode.CONFLICT.getCode(), "ISBN已被其他图书使用", null);
        }
        
        // 更新图书信息
        Book book = new Book();
        BeanUtils.copyProperties(updateDTO, book);
        book.setId(id);
        book.setUpdateTime(LocalDateTime.now());
        
        boolean updated = updateById(book);
        if (!updated) {
            return Result.fail(ResultCode.FAIL.getCode(), "更新图书失败", null);
        }
        
        // 返回更新后的图书信息
        Book updatedBook = getById(id);
        BookVO bookVO = convertToVO(updatedBook);
        return Result.success(bookVO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = "books", allEntries = true)
    public Result<Void> deleteBook(String id) {
        log.info("删除图书，ID：{}", id);
        
        // 检查图书是否存在
        Book book = getById(id);
        if (book == null) {
            return Result.fail(ResultCode.NOT_FOUND.getCode(), "图书不存在", null);
        }
        
        // 检查是否有未归还的借阅记录
        try {
            BookInventory inventory = bookInventoryMapper.selectByBookId(id);
            if (inventory != null && inventory.getBorrowedCopies() != null && inventory.getBorrowedCopies() > 0) {
                return Result.fail(ResultCode.PRECONDITION_FAILED.getCode(), "该图书还有未归还的副本，无法删除", null);
            }
        } catch (Exception e) {
            log.warn("检查图书库存状态失败，图书ID：{}，继续删除操作", id, e);
        }
        
        // 逻辑删除图书
        boolean deleted = removeById(id);
        if (!deleted) {
            return Result.fail(ResultCode.FAIL.getCode(), "删除图书失败", null);
        }
        
        return Result.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = "books", allEntries = true)
    public Result<Void> batchDeleteBooks(List<String> ids) {
        log.info("批量删除图书，IDs：{}", ids);
        
        // 检查是否有未归还的借阅记录
        for (String id : ids) {
            Book book = getById(id);
            if (book == null) {
                return Result.fail(ResultCode.NOT_FOUND.getCode(), "图书不存在，ID：" + id, null);
            }

            try {
                BookInventory inventory = bookInventoryMapper.selectByBookId(id);
                if (inventory != null && inventory.getBorrowedCopies() != null && inventory.getBorrowedCopies() > 0) {
                    return Result.fail(ResultCode.PRECONDITION_FAILED.getCode(),
                        "图书《" + book.getTitle() + "》还有未归还的副本，无法删除", null);
                }
            } catch (Exception e) {
                log.warn("检查图书库存状态失败，图书ID：{}，继续删除操作", id, e);
            }
        }
        
        // 批量删除
        boolean deleted = removeByIds(ids);
        if (!deleted) {
            return Result.fail(ResultCode.FAIL.getCode(), "批量删除图书失败", null);
        }
        
        return Result.success();
    }

    @Override
    @CacheEvict(value = "books", allEntries = true)
    public Result<Void> publishBook(String id) {
        log.info("上架图书，ID：{}", id);
        return updateBookStatus(id, 1);
    }

    @Override
    @CacheEvict(value = "books", allEntries = true)
    public Result<Void> unpublishBook(String id) {
        log.info("下架图书，ID：{}", id);
        return updateBookStatus(id, 0);
    }

    @Override
    @CacheEvict(value = "books", allEntries = true)
    public Result<Void> recommendBook(String id) {
        log.info("推荐图书，ID：{}", id);
        return updateRecommendStatus(id, 1);
    }

    @Override
    @CacheEvict(value = "books", allEntries = true)
    public Result<Void> unrecommendBook(String id) {
        log.info("取消推荐图书，ID：{}", id);
        return updateRecommendStatus(id, 0);
    }

    @Override
    @Cacheable(value = "books", key = "'isbn:' + #isbn")
    public BookVO getBookByIsbn(String isbn) {
        log.info("根据ISBN查询图书，ISBN：{}", isbn);
        return bookMapper.selectBookByIsbn(isbn);
    }

    @Override
    public PageResult<BookVO> getBooksByCategory(String categoryId, BookQuery query) {
        log.info("根据分类查询图书，分类ID：{}，查询条件：{}", categoryId, query);

        Page<BookVO> page = query.toPage();
        IPage<BookVO> result = bookMapper.selectBooksByCategory(page, categoryId, query);

        return PageResult.of(result.getRecords(), result.getTotal(), result.getCurrent(), result.getSize());
    }

    @Override
    public PageResult<BookVO> getBooksByAuthor(String authorId, BookQuery query) {
        log.info("根据作者查询图书，作者ID：{}，查询条件：{}", authorId, query);

        Page<BookVO> page = query.toPage();
        IPage<BookVO> result = bookMapper.selectBooksByAuthor(page, authorId, query);

        return PageResult.of(result.getRecords(), result.getTotal(), result.getCurrent(), result.getSize());
    }

    @Override
    public PageResult<BookVO> getBooksByPublisher(String publisherId, BookQuery query) {
        log.info("根据出版社查询图书，出版社ID：{}，查询条件：{}", publisherId, query);

        Page<BookVO> page = query.toPage();
        IPage<BookVO> result = bookMapper.selectBooksByPublisher(page, publisherId, query);

        return PageResult.of(result.getRecords(), result.getTotal(), result.getCurrent(), result.getSize());
    }

    @Override
    public PageResult<BookVO> searchBooks(String keyword, BookQuery query) {
        log.info("搜索图书，关键词：{}，查询条件：{}", keyword, query);

        Page<BookVO> page = query.toPage();
        IPage<BookVO> result = bookMapper.searchBooks(page, keyword, query);

        return PageResult.of(result.getRecords(), result.getTotal(), result.getCurrent(), result.getSize());
    }

    @Override
    @Cacheable(value = "books", key = "'recommended:' + #query.hashCode()")
    public PageResult<BookVO> getRecommendedBooks(BookQuery query) {
        log.info("获取推荐图书，查询条件：{}", query);

        Page<BookVO> page = query.toPage();
        IPage<BookVO> result = bookMapper.selectRecommendedBooks(page, query);

        return PageResult.of(result.getRecords(), result.getTotal(), result.getCurrent(), result.getSize());
    }

    @Override
    @Cacheable(value = "books", key = "'new:' + #query.hashCode()")
    public PageResult<BookVO> getNewBooks(BookQuery query) {
        log.info("获取新书，查询条件：{}", query);

        Page<BookVO> page = query.toPage();
        IPage<BookVO> result = bookMapper.selectNewBooks(page, query);

        return PageResult.of(result.getRecords(), result.getTotal(), result.getCurrent(), result.getSize());
    }

    @Override
    @Cacheable(value = "books", key = "'popular:' + #query.hashCode()")
    public PageResult<BookVO> getPopularBooks(BookQuery query) {
        log.info("获取热门图书，查询条件：{}", query);

        Page<BookVO> page = query.toPage();
        IPage<BookVO> result = bookMapper.selectPopularBooks(page, query);

        return PageResult.of(result.getRecords(), result.getTotal(), result.getCurrent(), result.getSize());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = "books", allEntries = true)
    public Result<Void> updateBookStock(String bookId, Integer totalCopies, Integer availableCopies) {
        log.info("更新图书库存，图书ID：{}，总库存：{}，可借阅库存：{}", bookId, totalCopies, availableCopies);
        
        int updated = bookMapper.updateBookStock(bookId, totalCopies, availableCopies);
        if (updated == 0) {
            return Result.fail(ResultCode.FAIL.getCode(), "更新图书库存失败", null);
        }
        
        return Result.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = "books", allEntries = true)
    public Result<Void> incrementBorrowCount(String bookId) {
        log.info("增加图书借阅次数，图书ID：{}", bookId);
        
        int updated = bookMapper.incrementBorrowCount(bookId);
        if (updated == 0) {
            return Result.fail(ResultCode.FAIL.getCode(), "更新借阅次数失败", null);
        }
        
        return Result.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = "books", allEntries = true)
    public Result<Void> updateBookRating(String bookId, Double rating) {
        log.info("更新图书评分，图书ID：{}，评分：{}", bookId, rating);
        
        // 这里应该重新计算评分和评价数量
        // 简化实现，实际应该查询所有评价重新计算
        int updated = bookMapper.updateBookRating(bookId, rating, null);
        if (updated == 0) {
            return Result.fail(ResultCode.FAIL.getCode(), "更新图书评分失败", null);
        }
        
        return Result.success();
    }

    @Override
    public Result<String> importBooks(List<BookCreateDTO> books) {
        log.info("导入图书数据，数量：{}", books.size());

        if (books == null || books.isEmpty()) {
            return Result.fail(ResultCode.PARAM_ERROR.getCode(), "导入数据不能为空", null);
        }

        int successCount = 0;
        int failCount = 0;
        StringBuilder errorMessages = new StringBuilder();

        for (int i = 0; i < books.size(); i++) {
            BookCreateDTO bookDTO = books.get(i);
            try {
                // 数据验证
                if (bookDTO.getTitle() == null || bookDTO.getTitle().trim().isEmpty()) {
                    failCount++;
                    errorMessages.append("第").append(i + 1).append("行：图书标题不能为空；");
                    continue;
                }

                if (bookDTO.getIsbn() != null && checkIsbnExists(bookDTO.getIsbn(), null)) {
                    failCount++;
                    errorMessages.append("第").append(i + 1).append("行：ISBN已存在；");
                    continue;
                }

                // 创建图书
                Result<BookVO> createResult = createBook(bookDTO);
                if (createResult.isSuccess()) {
                    successCount++;
                } else {
                    failCount++;
                    errorMessages.append("第").append(i + 1).append("行：").append(createResult.getMsg()).append("；");
                }
            } catch (Exception e) {
                failCount++;
                errorMessages.append("第").append(i + 1).append("行：").append(e.getMessage()).append("；");
                log.error("导入第{}行数据失败", i + 1, e);
            }
        }

        String resultMessage = String.format("导入完成，成功：%d条，失败：%d条", successCount, failCount);
        if (failCount > 0) {
            resultMessage += "。失败原因：" + errorMessages.toString();
        }

        log.info("图书数据导入完成，成功：{}条，失败：{}条", successCount, failCount);
        return Result.success(resultMessage);
    }

    @Override
    public Result<String> exportBooks(BookQuery query) {
        log.info("导出图书数据，查询条件：{}", query);

        try {
            // 1. 查询数据
            if (query == null) {
                query = new BookQuery();
            }

            // 设置较大的分页大小以获取所有数据
            query.setSize(10000); // 最多导出10000条记录
            PageResult<BookVO> pageResult = getBookPage(query);

            if (pageResult == null || pageResult.getRecords() == null || pageResult.getRecords().isEmpty()) {
                return Result.fail(ResultCode.NOT_FOUND.getCode(), "没有找到符合条件的图书数据", null);
            }

            // 2. 生成Excel文件路径
            String timestamp = String.valueOf(System.currentTimeMillis());
            String fileName = "books_export_" + timestamp + ".xlsx";
            String filePath = "/exports/" + fileName;

            // 3. 这里应该实现实际的Excel生成逻辑
            // 由于没有具体的Excel工具类，这里只是模拟
            log.info("模拟生成Excel文件，包含{}条记录，文件路径：{}", pageResult.getRecords().size(), filePath);

            // 实际项目中，这里应该：
            // - 使用EasyExcel或Apache POI生成Excel文件
            // - 将文件保存到指定目录
            // - 返回文件的访问URL或下载链接

            String resultMessage = String.format("导出成功，共%d条记录，文件：%s",
                pageResult.getRecords().size(), fileName);

            log.info("图书数据导出完成，记录数：{}，文件：{}", pageResult.getRecords().size(), fileName);
            return Result.success(resultMessage);

        } catch (Exception e) {
            log.error("导出图书数据失败", e);
            return Result.fail(ResultCode.INTERNAL_SERVER_ERROR.getCode(), "导出失败：" + e.getMessage(), null);
        }
    }

    /**
     * 检查ISBN是否已存在
     */
    @Override
    public boolean checkIsbnExists(String isbn, String excludeId) {
        LambdaQueryWrapper<Book> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Book::getIsbn, isbn);
        if (StringUtils.hasText(excludeId)) {
            wrapper.ne(Book::getId, excludeId);
        }
        return count(wrapper) > 0;
    }

    /**
     * 更新图书状态
     */
    private Result<Void> updateBookStatus(String id, Integer status) {
        Book book = new Book();
        book.setId(id);
        book.setStatus(status);
        book.setUpdateTime(LocalDateTime.now());
        
        boolean updated = updateById(book);
        if (!updated) {
            return Result.fail(ResultCode.FAIL.getCode(), "更新图书状态失败", null);
        }
        
        return Result.success();
    }

    /**
     * 更新推荐状态
     */
    private Result<Void> updateRecommendStatus(String id, Integer isRecommended) {
        Book book = new Book();
        book.setId(id);
        book.setIsRecommended(isRecommended);
        book.setUpdateTime(LocalDateTime.now());
        
        boolean updated = updateById(book);
        if (!updated) {
            return Result.fail(ResultCode.FAIL.getCode(), "更新推荐状态失败", null);
        }
        
        return Result.success();
    }

    /**
     * 获取相关图书
     */
    @Override
    public List<BookVO> getRelatedBooks(String bookId, Integer limit) {
        log.info("获取相关图书，图书ID：{}，限制数量：{}", bookId, limit);

        // 实现相关图书推荐逻辑
        // 1. 根据分类、作者、标签等找相关图书
        // 2. 按相关度排序
        // 3. 返回指定数量的结果

        Book book = getById(bookId);
        if (book == null) {
            log.warn("图书不存在，无法获取相关图书，图书ID：{}", bookId);
            return new ArrayList<>();
        }

        List<BookVO> relatedBooks = new ArrayList<>();
        int requestLimit = limit != null ? limit : 10;

        try {
            // 策略1：同分类的其他图书（权重最高）
            if (book.getCategoryId() != null) {
                LambdaQueryWrapper<Book> categoryWrapper = new LambdaQueryWrapper<>();
                categoryWrapper.eq(Book::getCategoryId, book.getCategoryId())
                              .ne(Book::getId, bookId)
                              .eq(Book::getStatus, 1)
                              .orderByDesc(Book::getCreateTime)
                              .last("LIMIT " + Math.min(requestLimit, 6));

                List<Book> categoryBooks = list(categoryWrapper);
                relatedBooks.addAll(categoryBooks.stream()
                                                .map(this::convertToVO)
                                                .collect(Collectors.toList()));
            }

            // 策略2：如果同分类图书不够，添加同作者的其他图书
            // 注意：由于Book实体没有直接的authorId字段，这里跳过同作者推荐
            // 在实际项目中，可以通过BookAuthor关联表查询同作者的其他图书
            if (relatedBooks.size() < requestLimit) {
                log.debug("同分类图书数量不足，跳过同作者推荐（需要通过BookAuthor关联表实现）");
            }

            // 策略3：如果还不够，添加同出版社的热门图书
            if (relatedBooks.size() < requestLimit && book.getPublisherId() != null) {
                LambdaQueryWrapper<Book> publisherWrapper = new LambdaQueryWrapper<>();
                publisherWrapper.eq(Book::getPublisherId, book.getPublisherId())
                               .ne(Book::getId, bookId)
                               .eq(Book::getStatus, 1)
                               .orderByDesc(Book::getCreateTime)
                               .last("LIMIT " + (requestLimit - relatedBooks.size()));

                List<Book> publisherBooks = list(publisherWrapper);
                relatedBooks.addAll(publisherBooks.stream()
                                                 .map(this::convertToVO)
                                                 .filter(bookVO -> relatedBooks.stream()
                                                                               .noneMatch(existing -> existing.getId().equals(bookVO.getId())))
                                                 .collect(Collectors.toList()));
            }

            // 确保不超过请求的数量
            List<BookVO> finalResult = relatedBooks.size() > requestLimit ?
                relatedBooks.subList(0, requestLimit) : relatedBooks;

            log.info("获取相关图书完成，图书ID：{}，返回数量：{}", bookId, finalResult.size());
            return finalResult;

        } catch (Exception e) {
            log.error("获取相关图书失败，图书ID：{}", bookId, e);
            return new ArrayList<>();
        }
    }

    // ========== BookInventoryService 方法实现 ==========

    @Override
    public Integer getAvailableCopies(String bookId) {
        log.debug("查询图书可借阅数量，图书ID：{}", bookId);

        if (bookId == null || bookId.trim().isEmpty()) {
            log.warn("图书ID为空");
            return 0;
        }

        try {
            BookInventory inventory = bookInventoryMapper.selectByBookId(bookId);
            if (inventory == null) {
                log.warn("未找到图书库存信息，图书ID：{}", bookId);
                return 0;
            }

            Integer availableCopies = inventory.getAvailableCopies();
            log.debug("图书可借阅数量：{}，图书ID：{}", availableCopies, bookId);
            return availableCopies != null ? availableCopies : 0;
        } catch (Exception e) {
            log.error("查询图书可借阅数量失败，图书ID：{}", bookId, e);
            return 0;
        }
    }

    @Override
    public boolean isStockSufficient(String bookId, Integer requestedQuantity) {
        log.debug("检查图书库存是否充足，图书ID：{}，请求数量：{}", bookId, requestedQuantity);

        if (bookId == null || bookId.trim().isEmpty()) {
            log.warn("图书ID为空");
            return false;
        }

        if (requestedQuantity == null || requestedQuantity <= 0) {
            log.warn("请求数量无效：{}", requestedQuantity);
            return false;
        }

        try {
            Boolean sufficient = bookInventoryMapper.isStockSufficient(bookId, requestedQuantity);
            boolean result = sufficient != null && sufficient;
            log.debug("库存检查结果：{}，图书ID：{}，请求数量：{}", result, bookId, requestedQuantity);
            return result;
        } catch (Exception e) {
            log.error("检查图书库存失败，图书ID：{}，请求数量：{}", bookId, requestedQuantity, e);
            return false;
        }
    }

    @Override
    public Result<Void> borrowBook(String bookId) {
        log.info("执行借书操作，图书ID：{}", bookId);

        if (bookId == null || bookId.trim().isEmpty()) {
            return Result.fail(ResultCode.PARAM_ERROR.getCode(), "图书ID不能为空", null);
        }

        try {
            // 检查图书是否存在
            Book book = getById(bookId);
            if (book == null) {
                return Result.fail(ResultCode.NOT_FOUND.getCode(), "图书不存在", null);
            }

            // 执行原子性借书操作
            int updateCount = bookInventoryMapper.borrowBook(bookId);
            if (updateCount > 0) {
                log.info("借书成功，图书ID：{}", bookId);
                return Result.success();
            } else {
                log.warn("借书失败，可能库存不足，图书ID：{}", bookId);
                return Result.fail(ResultCode.PRECONDITION_FAILED.getCode(), "图书库存不足或不可借阅", null);
            }
        } catch (Exception e) {
            log.error("借书操作失败，图书ID：{}", bookId, e);
            return Result.fail(ResultCode.INTERNAL_SERVER_ERROR.getCode(), "借书操作失败", null);
        }
    }

    @Override
    public Result<Void> returnBook(String bookId) {
        log.info("执行还书操作，图书ID：{}", bookId);

        if (bookId == null || bookId.trim().isEmpty()) {
            return Result.fail(ResultCode.PARAM_ERROR.getCode(), "图书ID不能为空", null);
        }

        try {
            // 检查图书是否存在
            Book book = getById(bookId);
            if (book == null) {
                return Result.fail(ResultCode.NOT_FOUND.getCode(), "图书不存在", null);
            }

            // 执行原子性还书操作
            int updateCount = bookInventoryMapper.returnBook(bookId);
            if (updateCount > 0) {
                log.info("还书成功，图书ID：{}", bookId);
                return Result.success();
            } else {
                log.warn("还书失败，可能没有借出记录，图书ID：{}", bookId);
                return Result.fail(ResultCode.PRECONDITION_FAILED.getCode(), "该图书没有借出记录", null);
            }
        } catch (Exception e) {
            log.error("还书操作失败，图书ID：{}", bookId, e);
            return Result.fail(ResultCode.INTERNAL_SERVER_ERROR.getCode(), "还书操作失败", null);
        }
    }

    @Override
    public Result<Void> reserveBook(String bookId) {
        log.info("执行预约图书操作，图书ID：{}", bookId);

        if (bookId == null || bookId.trim().isEmpty()) {
            return Result.fail(ResultCode.PARAM_ERROR.getCode(), "图书ID不能为空", null);
        }

        try {
            // 检查图书是否存在
            Book book = getById(bookId);
            if (book == null) {
                return Result.fail(ResultCode.NOT_FOUND.getCode(), "图书不存在", null);
            }

            // 执行原子性预约操作
            int updateCount = bookInventoryMapper.reserveBook(bookId);
            if (updateCount > 0) {
                log.info("预约图书成功，图书ID：{}", bookId);
                return Result.success();
            } else {
                log.warn("预约图书失败，可能库存不足，图书ID：{}", bookId);
                return Result.fail(ResultCode.PRECONDITION_FAILED.getCode(), "图书库存不足，无法预约", null);
            }
        } catch (Exception e) {
            log.error("预约图书操作失败，图书ID：{}", bookId, e);
            return Result.fail(ResultCode.INTERNAL_SERVER_ERROR.getCode(), "预约图书操作失败", null);
        }
    }

    @Override
    public Result<Void> cancelReservation(String bookId) {
        log.info("执行取消预约操作，图书ID：{}", bookId);

        if (bookId == null || bookId.trim().isEmpty()) {
            return Result.fail(ResultCode.PARAM_ERROR.getCode(), "图书ID不能为空", null);
        }

        try {
            // 检查图书是否存在
            Book book = getById(bookId);
            if (book == null) {
                return Result.fail(ResultCode.NOT_FOUND.getCode(), "图书不存在", null);
            }

            // 执行原子性取消预约操作
            int updateCount = bookInventoryMapper.cancelReservation(bookId);
            if (updateCount > 0) {
                log.info("取消预约成功，图书ID：{}", bookId);
                return Result.success();
            } else {
                log.warn("取消预约失败，可能没有预约记录，图书ID：{}", bookId);
                return Result.fail(ResultCode.PRECONDITION_FAILED.getCode(), "该图书没有预约记录", null);
            }
        } catch (Exception e) {
            log.error("取消预约操作失败，图书ID：{}", bookId, e);
            return Result.fail(ResultCode.INTERNAL_SERVER_ERROR.getCode(), "取消预约操作失败", null);
        }
    }

    // ========== BookStatisticsService 方法实现 ==========
    // 注意：incrementBorrowCount 和 updateBookRating 已在上面实现，这里不重复

    @Override
    public Result<Void> addBookReview(String bookId, Integer rating, boolean isPositive) {
        log.info("添加图书评价，图书ID：{}，评分：{}，是否好评：{}", bookId, rating, isPositive);

        if (bookId == null || bookId.trim().isEmpty()) {
            return Result.fail(ResultCode.PARAM_ERROR.getCode(), "图书ID不能为空", null);
        }

        try {
            // 检查图书是否存在
            Book book = getById(bookId);
            if (book == null) {
                return Result.fail(ResultCode.NOT_FOUND.getCode(), "图书不存在", null);
            }

            // 添加评价统计
            int positiveValue = isPositive ? 1 : 0;
            int negativeValue = isPositive ? 0 : 1;
            int updateCount = bookStatisticsMapper.addReview(bookId, positiveValue, negativeValue);

            if (updateCount > 0) {
                log.info("添加图书评价成功，图书ID：{}", bookId);
                return Result.success();
            } else {
                log.warn("添加图书评价失败，可能统计记录不存在，图书ID：{}", bookId);
                return Result.fail(ResultCode.NOT_FOUND.getCode(), "图书统计记录不存在", null);
            }
        } catch (Exception e) {
            log.error("添加图书评价失败，图书ID：{}", bookId, e);
            return Result.fail(ResultCode.INTERNAL_SERVER_ERROR.getCode(), "添加图书评价失败", null);
        }
    }

    @Override
    public Result<Void> removeBookReview(String bookId, boolean wasPositive) {
        log.info("移除图书评价，图书ID：{}，是否为好评：{}", bookId, wasPositive);

        if (bookId == null || bookId.trim().isEmpty()) {
            return Result.fail(ResultCode.PARAM_ERROR.getCode(), "图书ID不能为空", null);
        }

        try {
            // 检查图书是否存在
            Book book = getById(bookId);
            if (book == null) {
                return Result.fail(ResultCode.NOT_FOUND.getCode(), "图书不存在", null);
            }

            // 移除评价统计
            int positiveValue = wasPositive ? 1 : 0;
            int negativeValue = wasPositive ? 0 : 1;
            int updateCount = bookStatisticsMapper.removeReview(bookId, positiveValue, negativeValue);

            if (updateCount > 0) {
                log.info("移除图书评价成功，图书ID：{}", bookId);
                return Result.success();
            } else {
                log.warn("移除图书评价失败，可能统计记录不存在或评价数量为0，图书ID：{}", bookId);
                return Result.fail(ResultCode.PRECONDITION_FAILED.getCode(), "无法移除评价，可能评价数量为0", null);
            }
        } catch (Exception e) {
            log.error("移除图书评价失败，图书ID：{}", bookId, e);
            return Result.fail(ResultCode.INTERNAL_SERVER_ERROR.getCode(), "移除图书评价失败", null);
        }
    }

    @Override
    public Result<Void> incrementViewCount(String bookId) {
        log.debug("增加图书浏览次数，图书ID：{}", bookId);

        if (bookId == null || bookId.trim().isEmpty()) {
            return Result.fail(ResultCode.PARAM_ERROR.getCode(), "图书ID不能为空", null);
        }

        try {
            int updateCount = bookStatisticsMapper.incrementViewCount(bookId);
            if (updateCount > 0) {
                log.debug("增加图书浏览次数成功，图书ID：{}", bookId);
                return Result.success();
            } else {
                log.warn("增加图书浏览次数失败，可能统计记录不存在，图书ID：{}", bookId);
                return Result.fail(ResultCode.NOT_FOUND.getCode(), "图书统计记录不存在", null);
            }
        } catch (Exception e) {
            log.error("增加图书浏览次数失败，图书ID：{}", bookId, e);
            return Result.fail(ResultCode.INTERNAL_SERVER_ERROR.getCode(), "增加图书浏览次数失败", null);
        }
    }

    @Override
    public Result<Void> incrementFavoriteCount(String bookId) {
        log.info("增加图书收藏次数，图书ID：{}", bookId);

        if (bookId == null || bookId.trim().isEmpty()) {
            return Result.fail(ResultCode.PARAM_ERROR.getCode(), "图书ID不能为空", null);
        }

        try {
            int updateCount = bookStatisticsMapper.incrementFavoriteCount(bookId);
            if (updateCount > 0) {
                log.info("增加图书收藏次数成功，图书ID：{}", bookId);
                return Result.success();
            } else {
                log.warn("增加图书收藏次数失败，可能统计记录不存在，图书ID：{}", bookId);
                return Result.fail(ResultCode.NOT_FOUND.getCode(), "图书统计记录不存在", null);
            }
        } catch (Exception e) {
            log.error("增加图书收藏次数失败，图书ID：{}", bookId, e);
            return Result.fail(ResultCode.INTERNAL_SERVER_ERROR.getCode(), "增加图书收藏次数失败", null);
        }
    }

    @Override
    public Result<Void> decrementFavoriteCount(String bookId) {
        log.info("减少图书收藏次数，图书ID：{}", bookId);

        if (bookId == null || bookId.trim().isEmpty()) {
            return Result.fail(ResultCode.PARAM_ERROR.getCode(), "图书ID不能为空", null);
        }

        try {
            int updateCount = bookStatisticsMapper.decrementFavoriteCount(bookId);
            if (updateCount > 0) {
                log.info("减少图书收藏次数成功，图书ID：{}", bookId);
                return Result.success();
            } else {
                log.warn("减少图书收藏次数失败，可能统计记录不存在或收藏数量为0，图书ID：{}", bookId);
                return Result.fail(ResultCode.PRECONDITION_FAILED.getCode(), "无法减少收藏次数，可能收藏数量为0", null);
            }
        } catch (Exception e) {
            log.error("减少图书收藏次数失败，图书ID：{}", bookId, e);
            return Result.fail(ResultCode.INTERNAL_SERVER_ERROR.getCode(), "减少图书收藏次数失败", null);
        }
    }

    @Override
    public Result<Void> incrementShareCount(String bookId) {
        log.info("增加图书分享次数，图书ID：{}", bookId);

        if (bookId == null || bookId.trim().isEmpty()) {
            return Result.fail(ResultCode.PARAM_ERROR.getCode(), "图书ID不能为空", null);
        }

        try {
            int updateCount = bookStatisticsMapper.incrementShareCount(bookId);
            if (updateCount > 0) {
                log.info("增加图书分享次数成功，图书ID：{}", bookId);
                return Result.success();
            } else {
                log.warn("增加图书分享次数失败，可能统计记录不存在，图书ID：{}", bookId);
                return Result.fail(ResultCode.NOT_FOUND.getCode(), "图书统计记录不存在", null);
            }
        } catch (Exception e) {
            log.error("增加图书分享次数失败，图书ID：{}", bookId, e);
            return Result.fail(ResultCode.INTERNAL_SERVER_ERROR.getCode(), "增加图书分享次数失败", null);
        }
    }

    /**
     * 转换为VO对象
     */
    private BookVO convertToVO(Book book) {
        BookVO bookVO = new BookVO();
        BeanUtils.copyProperties(book, bookVO);
        return bookVO;
    }
}
